﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using FileHelpers;

namespace SecurityModule.Parsers.Format2014
{
    /// <summary>
    /// Parses address files provided by IDOR as of 2014, this format is still the used one by May 2016 (last update of this library), this class uses <see cref="FileHelperEngine{T}"/> to parse the CSV file.
    /// </summary>
    public class AddressParser : IParser
    {
        /// <summary>
        /// Returns true if the file correponds with IDOR address format as of 2014.
        /// </summary>
        /// <param name="data">Data to be processed as plain text.</param>
        /// <returns>True if the parser can process file, false otherwise.</returns>
        /// /// <exception cref="FileFormatException">Thrown when the file can't be processed structurally by <see cref="FileHelperEngine{T}"/>.</exception>
        public bool CanParse(string data)
        {
            var end = data.IndexOf('\n');
            if (end < 0)
                end = data.Length;
            var line = data.Substring(0, end);
            if (line.Count(c => c == ';') != 12)
                return false;
            var cells = line.Split(new[] { ';' }, StringSplitOptions.None);
            int i;
            if (cells[0].Length != 9) // Account number 9999-9999
                return false;
            if (cells[0][4] != '-') // Account number 9999-9999
                return false;
            if (!int.TryParse(cells[0].Replace("-", ""), out i)) // Account number 9999-9999
                return false;
            if (cells[2].Length != 2) // Location Code: CL, PL, TL
                return false;
            if (cells[2][1] != 'L') // Location Code: CL, PL, TL
                return false;
            if (!int.TryParse(cells[3], out i)) // SIC
                return false;
            return true;
        }
        /// <summary>
        /// Parses the provided data and returns a list of <see cref="ParseResultItem"/>.
        /// </summary>
        /// <param name="data">Data to be processed as plain text.</param>
        /// <returns>A list of <see cref="ParseResultItem"/> each with ResultKind set to <see cref="ResultKind.Address"/> and TaxItems set to null.</returns>
        /// <exception cref="FileHelpersException">Thrown when the provided data can't be parsed using this parser.</exception>
        public List<ParseResultItem> Parse(string data)
        {
            var e = new FileHelperEngine<AddressLine>();
            var lines = e.ReadString(data);
            return lines.Select(line => new ParseResultItem
                                                      {
                                                          AccountNum = line.AccountNumber,
                                                          Site = line.Site,
                                                          SIC = line.SIC.ToString(CultureInfo.InvariantCulture),
                                                          CompanyName = line.CompanyName,
                                                          CompanyName2 = line.CompanyName2,
                                                          Address1 = line.Address1,
                                                          Address2 = line.Address2,
                                                          City = line.City,
                                                          State = line.State,
                                                          ZipCode = line.Zip,
                                                          LocationCode = line.LocationCode,
                                                          ResultKind = ResultKind.Address
                                                      }).ToList();
        }
    }
}
